package com.imut.lagain.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imut.lagain.entity.AccessLog;
import com.imut.lagain.service.IAccessLogService;
import com.imut.lagain.util.JwtUtil;

import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.*;


import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 访问日志控制器
 */
@RestController
@RequestMapping("/api/access-log")
@RequiredArgsConstructor
@Validated
public class AccessLogController {
    private static final Logger log = LoggerFactory.getLogger(AccessLogController.class);

    private final IAccessLogService accessLogService;
    private final JwtUtil jwtUtil;
    
    /**
     * 分页查询访问日志
     * @param authorization JWT令牌
     * @param page 页码
     * @param size 每页大小
     * @param userId 用户ID
     * @param path 访问路径
     * @param method 请求方法
     * @param ipAddress IP地址
     * @param statusCode 状态码
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 访问日志列表
     */
    @GetMapping
    public ResponseEntity<Map<String, Object>> getAccessLogs(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @RequestParam(defaultValue = "1") @Min(1) @Max(1000) int page,
            @RequestParam(defaultValue = "20") @Min(1) @Max(100) int size,
            @RequestParam(required = false) @Min(1) Long userId,
            @RequestParam(required = false) @Size(max = 500) String path,
            @RequestParam(required = false) @Pattern(regexp = "^(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)$") String method,
            @RequestParam(required = false) @Pattern(regexp = "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$|^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$") String ipAddress,
            @RequestParam(required = false) @Min(100) @Max(599) Integer statusCode,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            IPage<AccessLog> logPage = accessLogService.getLogsByConditions(
                    userId, path, method, ipAddress, statusCode, startTime, endTime, page, size);
            
            response.put("success", true);
            response.put("data", logPage);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to get access logs", e);
            response.put("success", false);
            response.put("message", "获取访问日志失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
    
    /**
     * 根据用户ID查询访问日志
     * @param authorization JWT令牌
     * @param userId 用户ID
     * @param page 页码
     * @param size 每页大小
     * @return 访问日志列表
     */
    @GetMapping("/user/{userId}")
    public ResponseEntity<Map<String, Object>> getLogsByUserId(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @PathVariable @Min(1) Long userId,
            @RequestParam(defaultValue = "1") @Min(1) @Max(1000) int page,
            @RequestParam(defaultValue = "20") @Min(1) @Max(100) int size) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            Page<AccessLog> pageParam = new Page<>(page, size);
            IPage<AccessLog> logPage = accessLogService.getLogsByUserId(userId, pageParam);
            
            response.put("success", true);
            response.put("data", logPage);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to get logs by user id", e);
            response.put("success", false);
            response.put("message", "获取用户访问日志失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
    
    /**
     * 根据访问路径查询日志
     * @param authorization JWT令牌
     * @param path 访问路径
     * @param page 页码
     * @param size 每页大小
     * @return 访问日志列表
     */
    @GetMapping("/path")
    public ResponseEntity<Map<String, Object>> getLogsByPath(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @RequestParam @NotBlank @Size(max = 500) String path,
            @RequestParam(defaultValue = "1") @Min(1) @Max(1000) int page,
            @RequestParam(defaultValue = "20") @Min(1) @Max(100) int size) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            Page<AccessLog> pageParam = new Page<>(page, size);
            IPage<AccessLog> logPage = accessLogService.getLogsByPath(path, pageParam);
            
            response.put("success", true);
            response.put("data", logPage);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to get logs by path", e);
            response.put("success", false);
            response.put("message", "获取路径访问日志失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
    
    /**
     * 获取错误日志
     * @param authorization JWT令牌
     * @param page 页码
     * @param size 每页大小
     * @return 错误日志列表
     */
    @GetMapping("/errors")
    public ResponseEntity<Map<String, Object>> getErrorLogs(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @RequestParam(defaultValue = "1") @Min(1) @Max(1000) int page,
            @RequestParam(defaultValue = "20") @Min(1) @Max(100) int size) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            Page<AccessLog> pageParam = new Page<>(page, size);
            IPage<AccessLog> errorLogs = accessLogService.getErrorLogs(pageParam);
            
            response.put("success", true);
            response.put("data", errorLogs);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to get error logs", e);
            response.put("success", false);
            response.put("message", "获取错误日志失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
    
    /**
     * 获取访问统计信息
     * @param authorization JWT令牌
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计信息
     */
    @GetMapping("/stats")
    public ResponseEntity<Map<String, Object>> getAccessStats(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            Map<String, Object> stats = accessLogService.getAccessStatistics(startTime, endTime);
            
            response.put("success", true);
            response.put("data", stats);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to get access stats", e);
            response.put("success", false);
            response.put("message", "获取访问统计失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
    
    /**
     * 获取热门访问路径
     * @param authorization JWT令牌
     * @param limit 限制数量
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 热门路径列表
     */
    @GetMapping("/popular-paths")
    public ResponseEntity<Map<String, Object>> getPopularPaths(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @RequestParam(defaultValue = "10") @Min(1) @Max(100) int limit,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            List<Map<String, Object>> popularPaths = accessLogService.getPopularPaths(startTime, endTime, limit);
            
            response.put("success", true);
            response.put("data", popularPaths);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to get popular paths", e);
            response.put("success", false);
            response.put("message", "获取热门路径失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
    
    /**
     * 获取活跃用户列表
     * @param authorization JWT令牌
     * @param limit 限制数量
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 活跃用户列表
     */
    @GetMapping("/active-users")
    public ResponseEntity<Map<String, Object>> getActiveUsers(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @RequestParam(defaultValue = "10") @Min(1) @Max(100) int limit,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            List<Map<String, Object>> activeUsers = accessLogService.getActiveUsers(startTime, endTime, limit);
            
            response.put("success", true);
            response.put("data", activeUsers);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to get active users", e);
            response.put("success", false);
            response.put("message", "获取活跃用户失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
    
    /**
     * 获取最近访问日志
     * @param authorization JWT令牌
     * @param limit 限制数量
     * @return 最近访问日志
     */
    @GetMapping("/recent")
    public ResponseEntity<Map<String, Object>> getRecentLogs(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @RequestParam(defaultValue = "10") @Min(1) @Max(100) int limit) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            List<AccessLog> recentLogs = accessLogService.getRecentLogs(limit);
            
            response.put("success", true);
            response.put("data", recentLogs);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to get recent logs", e);
            response.put("success", false);
            response.put("message", "获取最近日志失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
    
    /**
     * 清理过期日志
     * @param authorization JWT令牌
     * @param days 保留天数
     * @return 清理结果
     */
    @DeleteMapping("/cleanup")
    public ResponseEntity<Map<String, Object>> cleanupExpiredLogs(
            @RequestHeader("Authorization") @NotBlank String authorization,
            @RequestParam(defaultValue = "30") @Min(1) @Max(365) int days) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String token = authorization.replace("Bearer ", "");
            if (!jwtUtil.validateToken(token)) {
                response.put("success", false);
                response.put("message", "Token无效");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            LocalDateTime beforeTime = LocalDateTime.now().minusDays(days);
            int deletedCount = accessLogService.cleanupOldLogs(beforeTime);
            
            response.put("success", true);
            response.put("message", "清理完成");
            response.put("deletedCount", deletedCount);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Failed to cleanup expired logs", e);
            response.put("success", false);
            response.put("message", "清理过期日志失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }
}